<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>代码整合</title>
    <style>
        td{
            width: 80px;
            height: 40px;
        }
    </style>

</head>

<body>


<script>
    // -----------------------------
    // 5. 变量命名规则
    // -----------------------------
    /*
        一个 JavaScript 标识符必须以字母、下划线（_）或者美元符号（$）开头；后续的字符也可以是数字（0-9）。
        因为 JavaScript 语言是区分大小写的，所以字母可以是从“A”到“Z”的大写字母和从“a”到“z”的小写字母。

        注：JavaScript 对大小写敏感，myVariable 和 myvariable 是不同的。如果代码出现问题了，先检查一下大小写！
        注：不能使用JavaScript关键词。
     */
    // 5.1 Number_hits，temp99，function, $credit，_name，9age，name$ 这边几个变量名是否合法？

    // let Number_hits = 1 ;
    // let temp99 = 1 ;
    // // let function = 1 ;非法
    // let $credit = 1 ;
    // let _name = 1 ;
    // // let 9age = 1 ;非法
    // let name$ = 1 ;

    // -----------------------------
    // 5. 数组
    // -----------------------------
    // 5.1 声明一个数组，存储一些数字，字符串，布尔，null等值，并尝试打印

    // let Array = [12,78,21,"sasqqsdqsadas",true,null];
    // console.log(Array);

    // 5.2 尝试遍历输出上面的数组元素

    // for (let i = 0;i < Array.length;i++) {
    //     console.log(Array[i]);
    // }
    //
    // for (let i in Array){
    //     console.log(Array[i]);
    // }
    //
    // for (let i of Array){
    //     console.log(i);
    // }

    // 删除数组的最后一个元素 - pop()
    // let v = Array.pop(); //null
    // v = Array.pop();     //true
    // 数组的末尾添加新的元素 - push()
    // Array.push(10);      //",10]
    // console.log(Array);

    // -----------------------------
    // 6. 对象
    // -----------------------------
    // 6.1 声明一个用户对象，id为1，name为李逍遥，description为仙剑1主角，然后尝试打印出其中每个属性

    // let UserInfo = {id: 1,name:"李逍遥",description:"仙剑1主角"};
    // console.log(UserInfo);
    // console.log(UserInfo.length);

    // 6.2 尝试遍历输出上面的对象中的每个属性

    // for (let el in UserInfo){
    //     console.log(UserInfo[el]);
    // }

    // for (let a of UserInfo){
    //     console.log(a.value);
    // } //不行
    
    // for (let value of Object.keys(UserInfo)){
    //     console.log(value + "......" + UserInfo[value]);
    // }

    // --------------------------------------------------------------------
    // -- 练习
    // --------------------------------------------------------------------
    // 1. 尝试声明购物车相关数据
    //价格,店铺,商品名,型号,个人信息(地址),数量,总价,商品图片
    // let userInfo = {};//个人信息
    // //数据结构
    // let shoppingCartGoodsList = [ //保存商品信息
    //     {
    //         goodsId: 1,
    //         price: 9.9,
    //         name: "秋裤",
    //         shopName: "平平无奇小店",
    //         size: "M",
    //         num: 2,
    //         img: ""
    //     },
    //     {
    //         goodsId: 2,
    //         price: 19.9,
    //         name: "内衣",
    //         shopName: "平平无奇小店",
    //         size: "M",
    //         num: 2,
    //         img: ""
    //     }
    // ];
    // console.log(shoppingCartGoodsList);

    // ----------
    // --运算符--
    // ----------
    // -- 练习 --
    // ----------
    // 1. 让用户输入一个数，判断是否是水仙花数。
    //  水仙花数是指一个 3 位数，它的每个位上的数字的 3次幂之和等于它本身（例如：1^3 + 5^3+ 3^3 = 153）。
    // let x1 = window.parseFloat(prompt("请输入一个3位数字:"));
    // let hundred1 = parseInt(x1 / 100); //百位 153/100 = 1
    // console.log(hundred1);
    // let ten1 = parseInt(x1 / 10) % 10; //十位 153/10=15 % 10 ...5
    // console.log(ten1);
    // let t1 = parseInt(x1 % 10); //个位 153 % 10 ...3
    // console.log(t1);
    // console.log( ( (hundred1 ** 3 + ten1 ** 3 + t1 ** 3) === x1) ? "水仙花数" : "不是水仙花数"); // 153 370 371 407

    // 2. 输入一个年份, 判断输入年份是不是闰年
    //  闰年条件: ①能被4整除而不能被100整除；②能被400整除。
    // let n = window.parseFloat(prompt("请输入一个年份"));
    // // &&且 ||或  ? true : false
    // console.log( (n % 4 === 0 && n % 100 !== 0 || n % 400 === 0) ? "闰年" : "不是闰年");

    // 3. 用户购买商品，输入3个商品的价格，如果三个商品中有一个超过50元，或者总价超过100元，即可以打八五折，否则不打折
    //一个大于50或者三个加起来大于100 ? true : false
    // let a = window.parseFloat(prompt("请输入第一个商品价格"));
    // let b = window.parseFloat(prompt("请输入第二个商品价格"));
    // let c = window.parseFloat(prompt("请输入第三个商品价格"));
    // console.log(a + b + c);
    // console.log((a > 50 || b > 50 || c > 50 || (a + b + c) > 100) ? "可打85折" +
    //     "\t" + "折扣价" + (a + b + c)*0.85 : "不打折");

    // --------------------------------------------------------------------
    // -- 分支结构
    // --------------------------------------------------------------------
    /*
        语法:
            1.if (condition) {
                当条件为 true 时执行的代码
            }
            2.if (condition) {
                当条件为 true 时执行的代码
            } else {
                当条件为 false 时执行的代码
            }
            3.if (condition1) {
                当条件 condition1 为 true 时执行的代码
            } else if (condition2) {
                当条件 condition2 为 true 时执行的代码
            } ... else {
               上面条件都不满足时执行的代码
            }
            4.switch(expression) {
                case 变量1:
                // 语句1代码块
                case 变量2:
                // 语句2代码块
                break;
                ...
                default:
                // 条件都不满足，执行代码块
            }
    */
    // 3.1 输入1个数字,判断是否是素数。

    // let c = window.prompt("请输入一个数字:");
    // let boolean = true;
    // for (let j = 2;j < c;j++){
    //     if (c % j === 0){
    //         console.log("不是素数");
    //         boolean = false;
    //         break;  //避免多运行
    //     }
    // }
    // if (boolean){
    //     console.log("是素数");
    // }


    // --------------------------------------------------------------------
    // -- 循环
    // --------------------------------------------------------------------
    /*
        语法:
            1.while (条件) {
                循环体代码块
              }
            2.do {
                   循环体代码块
              }
              while (条件);
            3.for (①初始化; ②条件; ④循环后执行的表达式) {
                    ③循环代码块
              }
            4.for (变量 in 对象) {
                    代码块
              }
             注：其中变量为索引
            5.for (变量 of 对象) {
                    代码块
              }
             其中变量为值
            6.对象.forEach(function (item, index, arr) {
                    代码块
              });
             item表示元素, index表示下标, arr表示数组本身
            7.break: 循环中用户退出循环的控制语句。
              continue: 循环中用于直接执行下一个循环的控制语句。
    */
    // 7.1 和电脑一直玩一个猜拳的小游戏, 用户输入石头、剪刀、布, 然后和电脑生成的进行对比。并判断谁赢,
    //  如果输入: 退出, 那么该程序退出
    //  如果点击取消按钮：那么直接进入下一轮

    // while (true) {
    //     let arr = ["石头", "剪刀", "布"];
    //     let computer = arr[Math.floor(Math.random() * 3)];
    //     console.log(computer);
    //     let user = window.prompt("请输入石头,剪刀,布:");
    //     console.log(user);
    //     if (user === "退出") { //终止
    //         break
    //     }
    //     if (user == null) { //无值当取消,进入下一轮
    //         continue;
    //     }
    //
    //     if (computer === user) {
    //         console.log("平局");
    //     } else {
    //         if (computer === "石头" && user === "剪刀") {
    //             console.log("电脑赢");
    //         } else if (computer === "石头" && user === "布") {
    //             console.log("电脑输");
    //         } else if (computer === "剪刀" && user === "布") {
    //             console.log("电脑赢");
    //         } else if (computer === "剪刀" && user === "石头") {
    //             console.log("电脑输");
    //         } else if (computer === "布" && user === "石头") {
    //             console.log("电脑赢");
    //         } else if (computer === "布" && user === "剪刀") {
    //             console.log("电脑输");
    //         }
    //     }
    // }
    // ----------------------------------------------------
    // -- 练习
    // ----------------------------------------------------
    // 2. 求出所有的水仙花数，水仙化数为3位数，并且每位上的数字的立方和等于该数本身

    // let n = 100;
    // for (let i = 1000;i > n;n++){ //限制n的范围是三位数;
    //     if ( (parseInt(n / 100) ** 3 + parseInt((n /10) % 10) ** 3 + parseInt(n % 10) ** 3) === n ){
    //         console.log(n);
    //     }
    // }

    // 3. 打印1到100之间的素数。
    document.write("提醒:循环练习素数未完成.");

    // 4. 输出一个整数n, 求 1!+2!+3!+4!+…n!

    // <!-- 阶乘 -->
    // let n = parseInt(window.prompt("请输入一个整数"));
    // let sum = 0;
    // for (let i = 1; i <= n; i++){
    //     let product = 1;
    //     for (let j = 1; j <= i ; j++){
    //         product *= j;
    //     }
    //     sum += product;
    // }
    // console.log(sum);

    // 5. 打印九九乘法表, 用表格呈现。

    // for (let i = 1; i <= 9; i++){
    //     for (let j = 1; j <= i; j++){
    //         document.write(j + "*" + i + "=" + j*i + " ");
    //     }
    //     document.write("</<br>>")
    // }

    // document.write("<table>");
    // for (let i = 1; i <= 9; i++){
    //     document.write("<tr>");
    //     for (let j = 1; j <= i; j++){
    //         document.write("<td>");
    //         document.write(j + "*" + i + "=" + j*i + " ");
    //         document.write("</td>");
    //     }
    //     document.write("</tr>");
    //     document.write("</br>");
    // }
    // document.write("</table>");

    // 6. 打印杨辉三角

    // let lastArr = []; // 存储上一层的数据
    // let tempArr = []; // 临时存储本层数据
    //
    // console.log(1);
    // for (let i = 2; i < 10; i++){
    //     lastArr = tempArr;
    //     tempArr = [];
    //
    //     let str = "";
    //     str += "1" + " ";
    //     tempArr.push(1);
    //
    //     for (let j = 1; j < (i-1); j++){
    //         str += (lastArr[j-1] + lastArr[j]) + " "; // 等于上一层的前一个数字+当前位置数字
    //         tempArr.push(lastArr[j-1] + lastArr[j]);
    //     }
    //
    //     str += "1";
    //     tempArr.push(1);
    //
    //     console.log(str);
    // }

    // --------------------------------------------------------------------
    // -- 函数
    // --------------------------------------------------------------------
    // -------------------------------------------------------
    // -- 练习 -- 常规,匿名,arguments变量的,不定参数的,箭头,系统 --
    // -------------------------------------------------------
    // 1. 定义一个计算圆面积的函数areaOfCircle()，它有两个参数：
    //  r: 表示圆的半径；
    //  pi: 表示π的值，如果不传，则默认3.14

    // /*①.常规函数*/
    // function areaOfCircle(r, pi) {
    //     if (!pi){
    //         pi = 3.14;
    //     }
    //     console.log(pi * r * r);
    // }
    // areaOfCircle(2);

    // /*②.匿名函数*/
    // let f = function(r, pi){
    //     if (!pi){
    //         pi = 3.14;
    //     }
    //     console.log(pi * r * r);
    // }
    // f(2);

    // /*③.不定参数的函数*/

    // /*④.箭头函数*/

    // /*⑤.系统函数*/

    // 2. 声明一个匿名函数，传入1个数字，求绝对值

    // let f = function (num) {
    //     let result = num;
    //     if (num < 0){
    //         result = -num;
    //     }
    //     console.log(result);
    // };

    // 3. 声明一个没有参数的函数，使用arguments变量计算所有传入参数的和

    // function sum(){
    //     let sum = 0;
    //     for (let i in arguments){
    //         sum += arguments[i];
    //     }
    //     console.log(sum);
    // }

    // 4. 声明一个不定参数的函数，打印出所有传递的参数

    // function rest(...args){
    //     for (let i of args){
    //         console.log(i);
    //     }
    // }

    // 5. 声明一个数组，使用箭头函数进行遍历

    // let arr = ["内衣", "秋裤"];
    // let f = (arr) => {
    //     for (let v of arr){
    //         console.log(v);
    //     }
    // };

    // 6. 输出一个整数n, 求 1!+2!+3!+4!+…n!，使用1个函数封装n!

    // let n = 4;
    //
    // let sum = 0;
    // for (let i = 1; i <= n; i++){
    //     sum += factorial(i);
    // }
    // console.log(sum);
    //
    // /*
    // * 计算一个数字的阶乘
    // * */
    //
    // function factorial(num){
    //     let result = 1;
    //     for (let i = 1; i <= num; i++){
    //         result *= i;
    //     }
    //     return result;
    // }

    // 7. 求出所有的水仙花数，使用函数封装判断一个数是否是水仙花数。

    // function isFlowerNumber(num) {
    //     if (num >= 100 && num <= 999) {
    //         let hundred = Math.floor(num / 100);
    //         let ten = Math.floor((num % 100) / 10);
    //         let unitsDigit = num % 10;
    //         return (hundred ** 3 + ten ** 3 + unitsDigit ** 3) === num;
    //     }
    //     return false;
    // }
    // //console.log(isFlowerNumber(153));
    // //console.log(isFlowerNumber(154));
    // for (let i = 100; i <= 999; i++){
    //     if (isFlowerNumber(i)){
    //         console.log(i + "是水仙数");
    //     }
    // }

    // 8. 输入一个秒数, 然后开始倒计时到0秒, 最多10000秒

    // let inputSecond = parseInt(window.prompt("请输入一个秒数"));
    // if (inputSecond > 0 && inputSecond <= 10000) {
    //     //timer是定时器
    //     let timer = window.setInterval(function () {
    //
    //
    //         let hour = Math.floor(inputSecond / 3600);
    //         let minute = Math.floor((inputSecond % 3600) / 60);
    //         let second = inputSecond % 60;
    //         console.log(hour, minute, second);
    //
    //         let html = hour.toString().padStart(2, "0")
    //             + ":" + minute.toString().padStart(2, "0")
    //             + ":" + second.toString().padStart(2, "0");
    //         console.log(html);
    //
    //         document.getElementById("count-down").innerHTML = html; //把这个id标签的内容换成 html
    //
    //         console.log(inputSecond--);
    //
    //         if (inputSecond < 0) { //放开头要多考虑 = 0 时.
    //             document.getElementById("count-down").innerHTML = "End!!!";
    //             window.clearInterval(timer);
    //         }
    //
    //     }, 1000);
    // } else {
    //     console.log("请输入正确的数字");
    // }

    // 9. 计算现在到2021-09-01的时间差, 然后开始倒计时,并输出在页面上, 输出格式: x天x小时x分钟x秒

    // let date = new Date(); //获取当前时间对象
    // console.log(date);
    // let targetDate = new Date("2021-09-01"); //获取2021-09-01这个时间的对象
    // console.log("2021-09-01 这个时间的对象", targetDate);
    // let inputSecond = Math.floor((targetDate - date) / 1000);
    // console.log(targetDate - date);
    //
    // //timer是定时器
    // let timer = window.setInterval(function () {
    //
    //     let day = Math.floor(inputSecond / 86400);
    //     let hour = Math.floor((inputSecond % 86400) / 3600);
    //     let minute = Math.floor((inputSecond % 3600) / 60);
    //     let second = inputSecond % 60;
    //     console.log(hour, minute, second);
    //
    //     let html = day + "天"
    //         + hour.toString().padStart(2, "0") + "小时"
    //         + minute.toString().padStart(2, "0") + "分钟"
    //         + second.toString().padStart(2, "0") + "秒";
    //     console.log(html);
    //
    //     document.getElementById("count-down").innerHTML = html; //把这个id标签的内容换成 html
    //
    //     console.log(inputSecond--);
    //
    //     if (inputSecond < 0) { //放开头要多考虑 = 0 时.
    //         document.getElementById("count-down").innerHTML = "End!!!";
    //         window.clearInterval(timer);
    //     }
    //
    // }, 1000);

    // 10. 使用js做一个电子表, 显示: yyyy-mm-dd hh:mm:ss, 并能够随时间跳动

    // let timer = window.setInterval(function (){
    //     let date = new Date();
    //     console.log(date);
    //
    //     let year = date.getFullYear();
    //     console.log("年", year);
    //     let month = date.getMonth() + 1; // 0 ~ 11
    //     console.log("月", month);
    //     let day = date.getDate();
    //     console.log("日", day);
    //     let hour = date.getHours();
    //     let minute = date.getMinutes();
    //     let second = date.getSeconds();
    //
    //     let html = year + "-" + month.toString().padStart(2, "0") + "-"
    //         + day.toString().padStart(2, "0") + " "
    //         + hour.toString().padStart(2, "0") + ":"
    //         + minute.toString().padStart(2, "0") + ":"
    //         + second.toString().padStart(2, "0");
    //     document.getElementById("count-down").innerHTML = html;
    // }, 1000);
    document.write("提醒:函数要多看看多敲敲.");

    // --------------------------------------------------------------------
    // -- 面向对象
    // --------------------------------------------------------------------
    // 2.1 声明计应班学生类，有姓名、性别、生日、php分数属性，有相关set和get方法，有获取年龄的方法

    // function JYStudent(name, sex, birth, phpScore) {
    //     this.name = name;
    //     this.sex = sex;
    //     this.birth = birth;
    //     this.setName = function (name) {
    //         this.name = name;
    //     };
    //     this.getName = function () {
    //         return this.name;
    //     };
    //     this.setSex = function (sex) {
    //         this.sex = sex;
    //     };
    //     this.getSex = function () {
    //         return this.sex;
    //     };
    //     this.setBirth = function (birth) {
    //         this.birth = birth;
    //     };
    //     this.getBirht = function () {
    //         return this.birth;
    //     };
    //     this.setPhpScore = function (phpScore) {
    //         this.phpScore = phpScore;
    //     };
    //     this.getPhpScore = function () {
    //         return phpScore;
    //     };
    //     this.getAge = function () {
    //         let date = new Date();
    //         let year = date.getFullYear();
    //         console.log("今年", year);
    //
    //         let birthDate = new Date(this.birth);
    //         let birthYear = birthDate.getFullYear();
    //         console.log("生日", birthYear);
    //
    //         return year - birthYear;
    //     }
    // }
    // let student = new JYStudent("林河森", "男", "2000-11-30", "88");
    // console.log(student.getName(), student.getSex(), student.getAge(), student.getPhpScore());

    // 2.3 观察一下上面的两个类是不是和学生类的东西大量重复了？

    //------------------
    //--创建基类（父类）--
    //------------------
    // function Student(name, sex, birth) {
    //     this.name = name;
    //     this.sex = sex;
    //     this.birth = birth;
    //     this.setName = function (name) {
    //         this.name = name;
    //     };
    //     this.getName = function () {
    //         return this.name;
    //     };
    //     this.setSex = function (sex) {
    //         this.sex = sex;
    //     };
    //     this.getSex = function () {
    //         return this.sex;
    //     };
    //     this.setBirth = function (birth) {
    //         this.birth = birth;
    //     };
    //     this.getBirth = function () {
    //         return this.birth;
    //     };
    //     this.getAge = function () {
    //         let date = new Date();
    //         let year = date.getFullYear();
    //         console.log("今年", year);
    //
    //         let birthDate = new Date(this.birth);
    //         let birthYear = birthDate.getFullYear();
    //         console.log("生日", birthYear);
    //
    //         return year - birthYear;
    //     }
    // }

    // 2.4 改写计应班学生类，继承上例学生类

    // function JYStudent(phpScore) {
    //     this.phpScore = phpScore;
    //     this.setPhpScore = function (phpScore) {
    //         this.phpScore = phpScore;
    //     };
    //     this.getPhpScore = function () {
    //         return this.phpScore;
    //     };
    // }
    // JYStudent.prototype = new Student();
    //
    // let jyStudent = new JYStudent(80);
    // jyStudent.setName("万磁王");
    // console.log(jyStudent);
    // console.log(jyStudent.getName());
    // console.log(jyStudent.getBirth());
    // console.log(jyStudent.toString());

    document.write("提醒:面向对象继承.");
    // -----------------------------
    // 6. es6中的语法
    // -----------------------------
    /*
        es6中增加了class的语法糖，本质是根据上面实现的。
        语法：
            class 类名 {
                constructor(属性1, 属性2, ...) {
                    构造方法体
                }

                方法1名(参数1, 参数2, ...) {
                    方法体
                }
                方法2名(参数1, 参数2, ...) {
                    方法体
                }
                ...
            }
            注：类里声明方法，不用加function
            注：类里可以声明多个方法
     */
    // 6.1 使用新语法糖实现上面的学生类、计应班学生类、软件班学生类

    // class Studnet {
    //     constructor(name, sex, birth){
    //         this.name = name;
    //         this.sex = sex;
    //         this.birth = birth;
    //     }
    //     setName(name){
    //         this.name = name;
    //     }
    //     getName(){
    //         return this.name;
    //     }
    // }
    // let student = new Studnet("张三");
    // console.log(student);

    // 6.2 新语法糖和旧的用哪个？

    // 1.真正将需求转化成了代码
    // 2.写出可读的，容易维护的，方便理解的代码
    // 具情况论,特别适合OOP的就用Class。
    // O(Object对象)O(Oriented面向对象)P(Programming编程)面向对象编程
    /* OOP 只是一套帮助开发者设计和编写软件的方法论，
    * 但并不代表它能解决所有领域的问题，
    * 也不是能在所有编程语言的任何场景下都适用。
    * 我们应避免陷入这种教条主义。
    */

    // ----------------------------------------------------
    // -- 练习
    // ----------------------------------------------------
    // 1. 声明一个动物类，有名称属性，有睡觉方法。

    // function Animal(name) {
    //     this.name = name;
    //     this.sleep = function () {
    //         console.log("睡觉");
    //     }
    // }

    // 2. 声明一个斑马类，继承动物类，重写睡觉方法。

    // function Zebra() {
    //     this.sleep = function () {
    //         console.log("斑马站着睡觉");
    //     }
    // }
    // Zebra.prototype = new Animal();
    // let zebra = new Zebra();
    // zebra.sleep();

    // 3. 声明一个鱼类，继承动物类，重写睡觉方法。

    // function Fish() {
    //     this.sleep = function () {
    //         console.log("睁着眼睛睡觉");
    //     }
    // }
    // Fish.prototype = new Animal();
    // let fish = new Fish();
    // fish.sleep();

    // 4. 声明一个鸟类，继承动物类，重写睡觉方法。

    // function Bird() {
    //     this.sleep = function () {
    //         console.log("鸟的睡姿各种各样");
    //     }
    // }
    // Bird.prototype = new Animal();
    // let bird = new Bird();
    // bird.sleep();

    // 5. 声明一个人类，继承动物类，重写睡觉方法。

    // function Human() {
    //     this.sleep = function () {
    //         console.log("躺着睡,需要舒服的床");
    //     }
    // }
    // Human.prototype = new Animal();
    // let human = new Human();
    // human.sleep();

    // --------------------------------------------------------------------
    // -- 浏览器对象模型
    // --------------------------------------------------------------------
    // 1.6 设置一个按钮, 当点击这个按钮的时候, 询问是否关闭页面, 如果确认则关闭当期页面

    // document.getElementById("btn-close").onclick = function () {
    //     if (confirm("请确认是否关闭页面")){
    //         close();
    //     }
    // }

    // 3. 判断用户浏览器是否是全屏？
    // document.write("可用宽度: " + screen.availWidth);
    // document.write("可用高度: " + screen.availHeight);
    // if (screen.availWidth > outerWidth || screen.availHeight > outerHeight){
    //     console.log("不是全屏");
    // } else{
    //     console.log("是全屏");
    // }

    // --------------------------------------------------------------------
    // -- document（文档对象模型）
    // --------------------------------------------------------------------


</script>
</body>
</html>